#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

#define serverAddress "api.seniverse.com"
// #define SSID "CMCC-xfang"
// #define PASSWORD "13880257043"

char city[32] = "chengdu"; // 可以通过蓝牙配置城市
char API_KEY[32] = "SeYvi-UkOX2MJuKUz";

char ssid[32] = "YAN";
char password[32] = "Honorcube0ne";

HTTPClient http;
char cmd_buf[128];
int ret;

void ESP01_LOG(const char *str);
void get_3days_weather();
void ParseWeatherJson3days(String json);
void wifi_config(char *dat);
void city_config(char *dat);
void get_current_weather();
void ParseWeatherJson1days(String json);

void setup()
{
  Serial.begin(115200);
  ESP01_LOG("esp ready");
}
void loop()
{
  ret = Serial.readBytesUntil('\n', cmd_buf, sizeof(cmd_buf));
  if (ret > 0)
  {
    cmd_buf[ret] = 0;  //手动写入字符串结束符
    // printf("I:ret=%d\n",ret);
    // 有数据 则按照格式进行解析
    if (cmd_buf[0] != 0x45)
    {
      ESP01_LOG("header error");
    }
    else
    {
      // 重新配网
      if (cmd_buf[1] == 0x52)
      {
        wifi_config(cmd_buf + 2);
      }
      if(cmd_buf[1]== 0x43){
        city_config(cmd_buf + 2);
      }
      else if(cmd_buf[1] == 0x31){
        get_current_weather();
      }
      else if (cmd_buf[1] == 0x35)
      {
        get_3days_weather();
      }
    }
  }
}


void city_config(char *dat)
{
  int ret;
  char buf[128];
  memset(city, 0, sizeof(city));
  ret = sscanf(dat, "%s", city);
  if (ret == 1)
  {
    snprintf(buf, sizeof(buf), "city_config city:%s", city);
    ESP01_LOG(buf);
  }
  else
  {
    ESP01_LOG("city_config failed");
  }

}
void wifi_config(char *dat)
{
  int ret;
  char buf[128];
  memset(ssid, 0, sizeof(ssid));
  memset(password, 0, sizeof(password));
  ret = sscanf(dat, "%s %s", ssid, password);
  if (ret == 2)
  {
    snprintf(buf, sizeof(buf), "wifi_config ssid:%s password:%s", ssid, password);
    ESP01_LOG(buf);
  }
  else
  {
    ESP01_LOG("wifi_config failed");
  }
  
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  delay(500);
  WiFi.begin(ssid, password);
  int timeout = 60; //30s
  while (timeout--)
  {
    if (WiFi.status() != WL_CONNECTED)
    {
      delay(500);
    }
    else
    {
      ESP01_LOG("wifi_config ok");
      return;
    }
  }
  ESP01_LOG("wifi_config timeout");
}
void get_3days_weather() // 免费账号 只能获取 3天 天气
{
  String url = "https://api.seniverse.com/v3/weather/daily.json?key=" + String(API_KEY) + "&location=" + String(city) + "&language=zh-Hans&unit=c&start=0&days=5";
  // Serial.println(url);

  WiFiClientSecure espClient;
  espClient.setInsecure(); // 禁用证书验证
  http.begin(espClient, url);
  http.setTimeout(5000);
  int httpResponseCode = http.GET();

  if (httpResponseCode == HTTP_CODE_OK)
  {
    String payload = http.getString();
    // Serial.println(payload);
    ParseWeatherJson3days(payload);
  }
  else
  {
    ESP01_LOG("API Error");
    // Serial.print("I:API Error ");
    // Serial.println(httpResponseCode);
  }
  http.end(); // 关闭连接
}

void ESP01_LOG(const char *str)
{
  Serial.write(0x45);
  Serial.write(0x49);
  Serial.println(str);
}

void send2stm32(int index, String &date, int day_code, int temp_high, int temp_low, int hun, char wind)
{
  char buf[256] = {0};
  buf[0] = 0x45;
  buf[1] = 0x35; //'5' 
  buf[2] = '0'+index;
  // 查询多天天气
  // 1 2025-03-21 4 27 9 45 E
  snprintf(buf + 3, sizeof(buf) - 3, "%s %d %d %d %d %c",date.c_str(), day_code, temp_high, temp_low, hun, wind);
  Serial.printf("%s\n", buf);
}

void ParseWeatherJson1days(String json)
{
  //解析当天天气情况
  DynamicJsonDocument doc(1024);
  DeserializationError error = deserializeJson(doc, json);
  if (error){
    Serial.print("I:deserializeJson failed:");
    Serial.println(error.c_str());
    return;
  }
 // int day_code = doc["results"][0]["now"]["code"].as<int>();
  int current_temp = doc["results"][0]["now"]["temperature"].as<int>();

  char buf[256] = {0};
  buf[0] = 0x45;
  buf[1] = 0x31; //'1' 
  // buf[2] = current_temp;
  // 查询当天天气
  snprintf(buf + 2, sizeof(buf) - 2, "%2d", current_temp);
  Serial.printf("%s\n", buf);
}
void ParseWeatherJson3days(String json)
{
  // 解析天气返回的JSON数据 免费账号 有3天的结果
  // 解析 JSON 数据
  DynamicJsonDocument doc(2048);
  DeserializationError error = deserializeJson(doc, json);
  if (error)
  {
    Serial.print("I:deserializeJson failed:");
    Serial.println(error.c_str());
    return;
  }

  for (int i = 0; i < 3; i++)
  {
    char wind_status;
    String date = doc["results"][0]["daily"][i]["date"].as<String>();
    // String text = doc["results"][0]["daily"][i]["text_day"].as<String>();
    int code = doc["results"][0]["daily"][i]["code_day"].as<int>();
    float temp_high = doc["results"][0]["daily"][i]["high"].as<float>();
    float temp_low = doc["results"][0]["daily"][i]["low"].as<float>();
    String wind = doc["results"][0]["daily"][i]["wind_direction"].as<String>();
    float hum = doc["results"][0]["daily"][i]["humidity"].as<float>();

    if (wind == "东")
    {
      wind_status = '1';
    }
    else if (wind == "南")
    {
      wind_status = '2';
    }
    else if (wind == "西")
    {
      wind_status = '3';
    }
    else if (wind == "北")
    {
      wind_status = '4';
    }
    else if (wind == "东南" || wind == "南东")
    {
      wind_status = '5';
    }
    else if (wind == "西南" || wind == "南西")
    {
      wind_status = '6';
    }
    else if (wind == "东北" || wind == "北东")
    {
      wind_status = '7';
    }
    else if (wind == "西北" || wind == "北西")
    {
      wind_status = '8';
    }
    else
    {
      wind_status = '9';
    }
    send2stm32(i, date, code, (int)temp_high, (int)temp_low, (int)hum, wind_status);
  }
}




#if 1
void get_current_weather() // 获取当天天气
{
  String url = "https://api.seniverse.com/v3/weather/now.json?key=" + String(API_KEY) + "&location=" + String(city) + "&language=zh-Hans&unit=c";
  // Serial.println(url);
  //debug
  WiFiClientSecure espClient;
  espClient.setInsecure(); // 禁用证书验证
  http.begin(espClient, url);
  http.setTimeout(5000);
  int httpResponseCode = http.GET();

  if (httpResponseCode == HTTP_CODE_OK)
  {
    String payload = http.getString();
    // Serial.println(payload);
    //debug
    ParseWeatherJson1days(payload);
  }
  else
  {
    Serial.print("I:API Error ");
    Serial.println(httpResponseCode);
  }
  http.end(); // 关闭连接
}
#endif